package org.lonetree.tc.core;

import java.util.HashSet;
import java.util.Set;
import org.lonetree.tc.core.id.NaturaldentifiableItem;
import org.lonetree.tc.core.id.ValidatedIdentifier;


/**
 * Business class representing books (textbooks) in the system.
 * 
 * All interfaces between different system components should use objects of this
 * class to pass information about textbooks.
 */
public final class Book extends NaturaldentifiableItem{

	private String title;
	private Set<String> authors;
	private Set<BookComment> comments;
	private Set<Source> sources;
	private Set<Section> sections;
	private boolean optional;
	
	protected Book(Isbn isbn){
		this(isbn, null, null, null, null, null, false);
	}
	
	protected Book(Isbn isbn, String title, Set<String> authors, Set<BookComment> comments, Set<Source> sources, Set<Section> sections, boolean optional){
		super(isbn);
		
		this.title = title;
		this.authors = authors;
		this.comments = comments;
		this.sources = sources;
		this.sections = sections;
		
		if(authors == null)
			this.authors = new HashSet<String>();
		
		if(comments == null)
			this.comments = new HashSet<BookComment>();
		
		if(sources == null)
			this.sources = new HashSet<Source>();
		
		if(sections == null)
			this.sections = new HashSet<Section>();
	}
	
	/**
	 * Get the Isbn identifying the book.
	 *
	 * @return Isbn
	 */
	public Isbn getIsbn(){
		return (Isbn)getIdentifier();
	}
	
	/**
	 * Get the title of the book.
	 *
	 * @return title
	 */
	public String getTitle(){
		return title;
	}

	/**
	 * Get the authors of the book.
	 *
	 * @return author Set
	 */
	public Set<String> getAuthors(){
		return authors;
	}
	
	/**
	 * Get the comments for the book.
	 *
	 * @return comment Set
	 */
	public Set<BookComment> getComments(){
		return comments;
	}
	
	/**
	 * Get the sources for the book.
	 *
	 * @return sources Set
	 */
	public Set<Source> getSources(){
		return sources;
	}
	
	/**
	 * Get the sections the book is used in.
	 *
	 * @return sections Set
	 */
	public Set<Section> getSections(){
		return sections;
	}
	
	/**
	 * Set the title of the book.
	 *
	 * @param title - the new title
	 */
	public void setTitle(String title){
		this.title = title;
	}
	
	/**
	 * Check whether the book is optional.
	 *
	 * @return optional
	 */
	public boolean isOptional(){
		return optional;
	}
	
	/**
	 * Set whether the book is optional.
	 *
	 * @param optional
	 */
	public void setOptional(boolean optional){
		this.optional = optional;
	}
	
	protected String getIdentifierType(){
		return "isbn";
	}
	
	/**
	 * ValidatedIdentifier representing a 10 or 13 digit ISBN (International
	 * Standard Book Number, defined in ISO 2108:2005 - e.g. 032142672X or
	 * 978-0321426727). Isbns are the unique identifiers for all Book objects.
	 */
	public static class Isbn extends ValidatedIdentifier{
		
		/**
		 * Create an Isbn encapsulating the passed ISBN.
		 *
		 * @param isbn - the ISBN representing a book
		 * @throws ValidationException if the ISBN does not conform to ISBN
		 * 		   standards (see
		 * 		   http://en.wikipedia.org/wiki/International_Standard_Book_Number
		 * 		   and
		 * 		   http://www.iso.org/iso/iso_catalogue/catalogue_tc/catalogue_detail.htm?csnumber=36563
		 * 		   for more information)
		 */
		public Isbn(String isbn) throws ValidationException{
			super(isbn);
		}
		
		@Override
		protected String validateAndFix(String isbn) throws ValidationException{
			// IMPLEMENT Isbn.validate()
			return isbn;
		}
		
		/**
		 * Get the String representation of the ISBN.
		 *
		 * @return isbn
		 */
		public String getIsbnString(){
			return getIdentifierString();
		}
	}
}
